﻿Imports System.Reflection
Imports System.Reflection.Emit
Imports VBParser

Namespace Compiler.Semantic
    Public Class CompileUnitDescription
        Inherits NameContainer

        'A complete list of all types defined in this compile unit.
        Private m_TypeDescriptions As List(Of TypeDescription)

        Public ReadOnly Property TypeDescriptions() As IList(Of TypeDescription)
            Get
                Return m_TypeDescriptions
            End Get
        End Property

        'An anonymous namespace for module level names
        Private m_moduleNamespace As NamespaceDescription

        Private m_topLevelNamespaces As BindingTable(Of NamespaceDescription)
        Private m_allTypes As List(Of TypeDescription)
        Private m_allNamespaces As List(Of NamespaceDescription)

        Public Sub New()
            MyBase.New(Nothing)
            m_moduleNamespace = New NamespaceDescription(Me) With {.Name = Symbol.Get("$$<Module>")}
            m_topLevelNamespaces = New BindingTable(Of NamespaceDescription)
            m_allTypes = New List(Of TypeDescription)

            'add predefined module level namespace for top level type or members
            Dim result = m_topLevelNamespaces.Enter(ModuleNamespaceBinder, m_moduleNamespace)
            Debug.Assert(result)

            m_semanticErrorList = New List(Of SemanticError)
            m_referenceManager = New ReferenceManager()
        End Sub

        Public Function AddTopLevelNamespace(ByVal ns As NamespaceDescription) As Boolean
            Return m_topLevelNamespaces.Enter(New SymbolBinder(ns.Name), ns)
        End Function

        Public Sub AddType(ByVal type As TypeDescription)
            m_allTypes.Add(type)
        End Sub

        Public Overrides ReadOnly Property QualifiedName() As Qualifier
            Get
                Return Nothing
            End Get
        End Property

#Region "Module Namespace Support"
        Private NotInheritable Class _ModuleNamespaceBinder
            Inherits Binder

            Private Sub New()
            End Sub

            Shared Sub New()
                c_ModuleNamespaceBinder = New _ModuleNamespaceBinder()
            End Sub

            Public Overloads Overrides Function Equals(ByVal other As Binder) As Boolean
                If other Is Nothing Then Return False
                Return TypeOf other Is _ModuleNamespaceBinder
            End Function

            Public Overrides Function GetHashCode() As Integer
                Return 1
            End Function
        End Class

        Private Shared c_ModuleNamespaceBinder As _ModuleNamespaceBinder

        Public Shared ReadOnly Property ModuleNamespaceBinder() As Binder
            Get
                Return c_ModuleNamespaceBinder
            End Get
        End Property
#End Region

        Public Overrides Function SearchChild(ByVal childBinder As Binder) As NameContainer
            Return m_topLevelNamespaces.LookUp(childBinder)
        End Function

        Private m_semanticErrorList As List(Of SemanticError)
        Public ReadOnly Property SemanticErrorList() As IList(Of SemanticError)
            Get
                Return m_semanticErrorList
            End Get
        End Property

        Private m_referenceManager As ReferenceManager
        Public ReadOnly Property ReferenceManager() As ReferenceManager
            Get
                Return m_referenceManager
            End Get
        End Property

        Private m_specialTypes As SpecialTypeProvider
        Public ReadOnly Property SpecialTypes() As SpecialTypeProvider
            Get
                Return m_specialTypes
            End Get
        End Property

    End Class
End Namespace